package ${projectDomain}.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.unswift.annotation.api.Api;
import com.unswift.annotation.api.ApiField;
import com.unswift.annotation.api.ApiMethod;
import ${projectDomain}.adapter.system.SystemDictionaryAdapter;
import ${projectDomain}.adapter.system.SystemDictionaryTypeAdapter;
import ${projectDomain}.annotation.logger.OperatorLogger;
import ${projectDomain}.cache.CacheEnum;
import ${projectDomain}.enums.OperatorTypeEnum;
import ${projectDomain}.pojo.bo.system.dictionary.SystemDictionaryCreateBo;
import ${projectDomain}.pojo.bo.system.dictionary.SystemDictionaryDeleteBo;
import ${projectDomain}.pojo.bo.system.dictionary.SystemDictionaryPageBo;
import ${projectDomain}.pojo.bo.system.dictionary.SystemDictionaryTreeBo;
import ${projectDomain}.pojo.bo.system.dictionary.SystemDictionaryTypeBo;
import ${projectDomain}.pojo.bo.system.dictionary.SystemDictionaryUpdateBo;
import ${projectDomain}.pojo.bo.system.dictionary.SystemDictionaryViewBo;
import ${projectDomain}.pojo.dao.sql.Sql;
import ${projectDomain}.pojo.dao.system.dictionary.SystemDictionaryDataDo;
import ${projectDomain}.pojo.dao.system.dictionary.SystemDictionaryDeleteDo;
import ${projectDomain}.pojo.dao.system.dictionary.SystemDictionaryInsertDo;
import ${projectDomain}.pojo.dao.system.dictionary.SystemDictionaryPageDo;
import ${projectDomain}.pojo.dao.system.dictionary.SystemDictionarySearchDo;
import ${projectDomain}.pojo.dao.system.dictionary.SystemDictionarySingleDo;
import ${projectDomain}.pojo.dao.system.dictionary.SystemDictionaryUpdateDo;
import ${projectDomain}.pojo.dao.system.dictionary.type.SystemDictionaryTypeDataDo;
import ${projectDomain}.pojo.vo.page.PageVo;
import ${projectDomain}.pojo.vo.system.dictionary.SystemDictionaryCreateVo;
import ${projectDomain}.pojo.vo.system.dictionary.SystemDictionaryDeleteVo;
import ${projectDomain}.pojo.vo.system.dictionary.SystemDictionaryPageVo;
import ${projectDomain}.pojo.vo.system.dictionary.SystemDictionaryTreeVo;
import ${projectDomain}.pojo.vo.system.dictionary.SystemDictionaryTypeVo;
import ${projectDomain}.pojo.vo.system.dictionary.SystemDictionaryUpdateVo;
import ${projectDomain}.pojo.vo.system.dictionary.SystemDictionaryViewVo;
import ${projectDomain}.utils.LoggerUtils;
import com.unswift.utils.ExceptionUtils;
import com.unswift.utils.ObjectUtils;
import com.unswift.utils.StringUtils;

@Service
@Api(value="数据字典服务", author="unswift", date="2023-08-13", version="1.0.0")
public class SystemDictionaryService extends BaseService{
	
	@Autowired
	@ApiField("数据字典公共服务")
	private SystemDictionaryAdapter systemDictionaryAdapter;
	
	@Autowired
	@ApiField("数据字典类型公共服务")
	private SystemDictionaryTypeAdapter systemDictionaryTypeAdapter;
	
	@ApiMethod(value="查询系统部门树数据", params=@ApiField("树查询对象"), returns=@ApiField("包含查询数据的树对象"))
    public SystemDictionaryTreeVo findTreeList(SystemDictionaryTreeBo searchBo){
		SystemDictionaryTypeDataDo type = systemDictionaryTypeAdapter.findByCode(searchBo.getType());
        SystemDictionarySearchDo search=this.convertPojo(searchBo, SystemDictionarySearchDo.class);
        systemDictionaryAdapter.setFieldToLike(search, "value", ObjectUtils.asList("key_", "value_"));
        systemDictionaryAdapter.addOrderBy(search, "parent_id_", Sql.ORDER_BY_ASC);
        systemDictionaryAdapter.addOrderBy(search, "sort_", Sql.ORDER_BY_ASC);
        SystemDictionaryTreeVo root=new SystemDictionaryTreeVo(-1L, type.getName(), true, false, type.getCode(), type.getName());
        List<SystemDictionaryDataDo> list = systemDictionaryAdapter.findList(search);
        if(ObjectUtils.isNotEmpty(list)) {
        	String spreadPath=null;
        	if(ObjectUtils.isNotEmpty(searchBo.getSpreadId())){
        		SystemDictionaryDataDo spreadDictionary=systemDictionaryAdapter.findById(searchBo.getSpreadId());
        		if(ObjectUtils.isNotEmpty(spreadDictionary)) {
        			spreadPath=spreadDictionary.getParentPath();
        		}
        	}
            Set<Long> ids=list.stream().map(r -> r.getId()).collect(Collectors.toSet());
            systemDictionaryAdapter.findParent(list, ids);
        	List<SystemDictionaryDataDo> rootList=list.stream().filter(r -> ObjectUtils.isEmpty(r.getParentId())).collect(Collectors.toList());
        	if(ObjectUtils.isEmpty(rootList)){
        		return root;
        	}
    		List<SystemDictionaryTreeVo> childList=new ArrayList<SystemDictionaryTreeVo>();
    		SystemDictionaryTreeVo childNode;
    		for (SystemDictionaryDataDo dictionary : rootList) {
    			childNode=new SystemDictionaryTreeVo(dictionary.getId(), String.format("%s（%s）", dictionary.getValue(), cacheAdapter.findLanguageByShortName(dictionary.getLanguage())), type.getCode(), type.getName());
    			if(ObjectUtils.isNotEmpty(spreadPath) && StringUtils.contains(spreadPath, dictionary.getId()+"", ".")){
    				childNode.setSpread(true);
    			}
    			childList.add(childNode);
    			systemDictionaryAdapter.parseDictionaryToTree(list, childNode, spreadPath, type);
			}
    		root.setChildren(childList);
        }
        return root;
    }
	
	@ApiMethod(value="查询数据字典分页数据", params=@ApiField("分页对象，包含分页信息及查询条件"), returns=@ApiField("包含查询数据的分页对象"))
	public PageVo<SystemDictionaryPageVo> findPageList(SystemDictionaryPageBo searchBo){
		SystemDictionaryPageDo search=this.convertPojo(searchBo, SystemDictionaryPageDo.class);//将Bo转换为So
		search.setFirstSize((search.getCurrPage()-1)*search.getPageSize());
		PageVo<SystemDictionaryDataDo> page=systemDictionaryAdapter.findPageList(search);//将Do转换为Vo
		return this.convertPage(page, SystemDictionaryPageVo.class);
	}
	
	@ApiMethod(value="根据类型查询数据字典数据", params=@ApiField("查询对象"), returns=@ApiField("包含查询数据的对象"))
	public List<SystemDictionaryTypeVo> findTypeList(SystemDictionaryTypeBo searchBo){
		SystemDictionarySearchDo search=this.convertPojo(searchBo, SystemDictionarySearchDo.class);//将Bo转换为So
		systemDictionaryAdapter.addWhereEquals(search, "language_", getLanguage(), null);
		systemDictionaryAdapter.addOrderBy(search, "sort_", Sql.ORDER_BY_ASC);
		List<SystemDictionaryDataDo> list=systemDictionaryAdapter.findList(search);
		return this.convertPojoList(list, SystemDictionaryTypeVo.class);//将Do转换为Vo
	}
	
	@ApiMethod(value="查询数据字典详情", params=@ApiField("详情业务实体，包含id字段"), returns=@ApiField("数据字典详情数据"))
	public SystemDictionaryViewVo view(SystemDictionaryViewBo viewBo){
		SystemDictionarySingleDo search=this.convertPojo(viewBo, SystemDictionarySingleDo.class);
		SystemDictionaryDataDo single=systemDictionaryAdapter.findSingle(search);
		return this.convertPojo(single, SystemDictionaryViewVo.class);//将Do转换为Vo
	}

	@OperatorLogger(type = OperatorTypeEnum.CREATE)
	@ApiMethod(value="创建数据字典", params=@ApiField("创建的业务实体"), returns=@ApiField("创建结果{0：未创建，1：已创建}"))
	public SystemDictionaryCreateVo create(SystemDictionaryCreateBo createBo){
		LoggerUtils.setModule(systemDictionaryAdapter.getModule());//设置日志所属模块
		SystemDictionaryInsertDo insert=this.convertPojo(createBo, SystemDictionaryInsertDo.class);//将Bo转换为Po
		int result=systemDictionaryAdapter.save(insert, true);
		LoggerUtils.setId(insert.getId());//创建日志需要设置数据id
		memoryCache.removeHash(CacheEnum.DICTIONARY_MAP.getKey(), createBo.getType());
		return new SystemDictionaryCreateVo(result);
	}
	
	@ApiMethod(value="更新数据字典", params=@ApiField("更新的业务实体"), returns=@ApiField("更新结果{0：未创建，1：已创建}"))
	public SystemDictionaryUpdateVo update(SystemDictionaryUpdateBo updateBo){
		LoggerUtils.setModule(systemDictionaryAdapter.getModule());//设置日志所属模块
		SystemDictionaryDataDo dictionary=systemDictionaryAdapter.findById(updateBo.getId());
		ExceptionUtils.empty(dictionary, "delete.object.not.exists", "数据字典项");//更新对象必须存在
		LoggerUtils.setOriginalData(dictionary);//设置日志原数据对象
		SystemDictionaryUpdateDo update=this.convertPojo(updateBo, SystemDictionaryUpdateDo.class);//将Bo转换为Po
		int result=systemDictionaryAdapter.update(update, true);
		memoryCache.removeHash(CacheEnum.DICTIONARY_MAP.getKey(), dictionary.getType());
		return new SystemDictionaryUpdateVo(result);
	}
	
	@ApiMethod(value="删除数据字典", params=@ApiField("删除业务实体，包含id字段"), returns=@ApiField("删除结果{0：未创建，1：已创建}"))
	public SystemDictionaryDeleteVo delete(SystemDictionaryDeleteBo deleteBo){
		LoggerUtils.setModule(systemDictionaryAdapter.getModule());//设置日志所属模块
		SystemDictionaryDeleteDo delete=this.convertPojo(deleteBo, SystemDictionaryDeleteDo.class);//将Bo转换为Po
		SystemDictionaryDataDo dictionary=systemDictionaryAdapter.findById(deleteBo.getId());
		ExceptionUtils.empty(dictionary, "delete.object.not.exists", "数据字典项");//删除对象必须存在
		int result=systemDictionaryAdapter.delete(delete);
		memoryCache.removeHash(CacheEnum.DICTIONARY_MAP.getKey(), dictionary.getType());
		return new SystemDictionaryDeleteVo(result);
	}
}
